package util

import (
	"fmt"
	"strings"

	"gitee.com/ChangPaoZhe/devops/apps/cmdb"
	"gitee.com/ChangPaoZhe/devops/apps/command"
	"gitee.com/ChangPaoZhe/devops/config"
	"github.com/rs/zerolog"
	"golang.org/x/crypto/ssh"
	"os/exec"
)

type SshImpl struct {
	logger zerolog.Logger
	UserName  string 
	Password string
	Port  int64
	Ipaddress  string 
}



const  (
	App_Name  = "ssh_utils"

)

func NewDefaultSshImpl(resources  *cmdb.Resource) *SshImpl {
	return &SshImpl{
		logger: config.C.Logs.Getlog(App_Name),
		UserName: resources.Username,
		Password: resources.Password,
		Ipaddress: resources.Ipaddress,
		Port: resources.Port,
	}
}


func (s *SshImpl) Address() string {
	return  fmt.Sprintf("%s:%d", s.Ipaddress,s.Port)
}

func (s *SshImpl)Ssh_Connect(input_param  *command.Input_Params)  (command.Ssh_Code,string,error) {
	config := &ssh.ClientConfig{
		User: s.UserName,
		Auth: []ssh.AuthMethod{
			ssh.Password(s.Password),
		},
		HostKeyCallback: ssh.InsecureIgnoreHostKey(),
	}
    cmd := exec.Command("ping", "-c", "1","-W","1",s.Ipaddress) // Linux系统上使用-c参数指定次数，Windows系统上使用-n参数
    err := cmd.Run()
    if err != nil {
        return command.Ssh_Code_PING_CONN_FAILED, "",fmt.Errorf("PING 测试失败: %v ip Address: %s", err,s.Ipaddress)
    }
	client,err:=ssh.Dial("tcp", s.Address(), config)
	if err != nil {
		return command.Ssh_Code_SSH_CONN_FAILED, "", err
	}
	defer client.Close()
	session, err := client.NewSession()
	if err != nil {
		s.logger.Error().Msg(fmt.Sprintf("Failed to create session: %s", err))
		return command.Ssh_Code_SSH_TIMEOUT, "", err
	}
	defer session.Close()
	command_exec:=""
	if  input_param.InputType==command.Input_Type_python  {
		command_exec=fmt.Sprintf("/usr/bin/python  %s",input_param.FilePath)
	}else if    input_param.InputType==command.Input_Type_shell  {
		command_exec=fmt.Sprintf("%s",input_param.FilePath)
	}else  {
		command_exec=fmt.Sprintf("%s",input_param.FilePath)
	}
	for  _,param:=range  input_param.Params {
		command_exec=fmt.Sprintf("%s %s", command_exec,param)
	}
	s.logger.Info().Msg(command_exec)
	output, err := session.Output(command_exec)
	if err != nil {
		s.logger.Error().Msg(fmt.Sprintf("Failed to run remote command: %s", err))
		return command.Ssh_Code_SSH_EXEC_FAILED, "", err 
	}
	s.logger.Info().Msg(fmt.Sprintf("code: %d,output: %s",command.Ssh_Code_SSH_CONN_SUCCESS,string(output[:])))
	return  command.Ssh_Code_SSH_CONN_SUCCESS,	strings.ReplaceAll(string(output),"\n", " "),nil
}